package org.osgroup.project;

import org.osgroup.visitor.BaseVisitor;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 游乐园类
 * 
 * <p>游乐园包含多个娱乐设施和美食街</p>
 * 
 * @author OS Group
 * @version 1.0
 */
public class Park {
    /** 游乐园名称 */
    private String parkName;
    
    /** 游乐园中的游客数量 */
    private int peopleNum;
    
    /** 在游乐园中的游客列表 */
    private List<BaseVisitor> visitors;
    
    /** 游乐园中的项目列表（包括美食街） */
    private List<BaseProject> projects;
    
    /** 随机数生成器 */
    private final Random random;
    
    /**
     * 默认构造函数
     */
    public Park() {
        this("欢乐游乐园");
    }
    
    /**
     * 构造游乐园
     * 
     * @param parkName 游乐园名称
     */
    public Park(String parkName) {
        this.parkName = parkName;
        this.visitors = new ArrayList<>();
        this.projects = new ArrayList<>();
        this.peopleNum = 0;
        this.random = new Random();
    }
    
    // ==================== 项目管理方法 ====================
    
    /**
     * 添加游乐项目
     * 
     * @param project 要添加的项目
     * @return true表示添加成功
     */
    public boolean addProject(BaseProject project) {
        if (project == null) {
            System.out.println("❌ 无法添加空项目");
            return false;
        }
        
        projects.add(project);
        System.out.println("✅ [" + parkName + "] 新增项目: " + project.getProjectName());
        return true;
    }
    
    /**
     * 移除游乐项目
     * 
     * @param project 要移除的项目
     * @return true表示移除成功
     */
    public boolean removeProject(BaseProject project) {
        if (projects.remove(project)) {
            System.out.println("✅ [" + parkName + "] 移除项目: " + project.getProjectName());
            return true;
        }
        System.out.println("❌ 项目不存在");
        return false;
    }
    
    /**
     * 获取项目列表
     * 
     * @return 项目列表的副本
     */
    public List<BaseProject> getProjects() {
        return new ArrayList<>(projects);
    }
    
    /**
     * 获取项目数量
     * 
     * @return 项目数量
     */
    public int getProjectCount() {
        return projects.size();
    }
    
    // ==================== 美食街管理方法 ====================
    
    /**
     * 为游乐园添加美食街（美食街也是一个项目）
     * 
     * @param foodStreet 美食街对象
     */
    public void setFoodStreet(FoodStreet foodStreet) {
        // 美食街作为项目添加到项目列表中
        if (!projects.contains(foodStreet)) {
            projects.add(foodStreet);
            System.out.println("✅ [" + parkName + "] 美食街 \"" + foodStreet.getFoodStreetName() + "\" 已开放");
        } else {
            System.out.println("⚠️  [" + parkName + "] 美食街已存在");
        }
    }
    
    /**
     * 获取美食街
     * 
     * @return 美食街对象，如果不存在则返回null
     */
    public FoodStreet getFoodStreet() {
        return findFoodStreetInProjects();
    }
    
    /**
     * 从项目中查找美食街
     * 
     * @return 找到的美食街，如果不存在则返回null
     */
    private FoodStreet findFoodStreetInProjects() {
        for (BaseProject project : projects) {
            if (project instanceof FoodStreet) {
                return (FoodStreet) project;
            }
        }
        return null;
    }
    
    // ==================== 游客管理方法 ====================
    
    /**
     * 游客进入游乐园
     * 
     * @param visitor 进入的游客
     * @return true表示成功进入
     */
    public boolean getIn(BaseVisitor visitor) {
        if (visitor == null) {
            System.out.println("❌ 游客信息无效");
            return false;
        }
        
        visitors.add(visitor);
        visitor.setStatus(true);
        peopleNum++;
        
        System.out.println("👋 游客 " + visitor.getName() + " 进入 " + parkName + 
                           " | 当前游客数: " + peopleNum);
        return true;
    }
    
    /**
     * 游客离开游乐园
     * 
     * @param visitor 离开的游客
     * @return true表示成功离开
     */
    public boolean getOut(BaseVisitor visitor) {
        if (visitor == null || !visitors.contains(visitor)) {
            System.out.println("❌ 游客不在园内");
            return false;
        }
        
        visitors.remove(visitor);
        visitor.setStatus(false);
        peopleNum--;
        
        System.out.println("👋 游客 " + visitor.getName() + " 离开 " + parkName + 
                           " | 当前游客数: " + peopleNum);
        return true;
    }
    
    // ==================== 美食街相关功能 ====================
    
    /**
     * 游客随机进入美食街就餐
     * 
     * @param visitor 要就餐的游客
     * @param mealCount 要吃的餐品数量
     */
    public void visitorGoToFoodStreet(BaseVisitor visitor, int mealCount) {
        FoodStreet foodStreet = getFoodStreet();
        
        if (foodStreet == null) {
            System.out.println("❌ [" + parkName + "] 美食街尚未开放");
            return;
        }
        
        if (!visitors.contains(visitor)) {
            System.out.println("❌ 游客 " + visitor.getName() + " 不在 " + parkName + " 内");
            return;
        }
        
        if (!foodStreet.isOpen()) {
            System.out.println("❌ 美食街已打烊，游客 " + visitor.getName() + " 无法就餐");
            return;
        }
        
        System.out.println("\n🍽️  游客 " + visitor.getName() + " 前往美食街就餐...");
        
        // 游客进入美食街
        foodStreet.visitorEnter(visitor);
        
        try {
            int mealsObtained = 0;
            
            while (mealsObtained < mealCount) {
                // 随机选择餐馆
                Restaurant restaurant = selectRandomRestaurant();
                
                if (restaurant == null) {
                    System.out.println("❌ 美食街暂无营业的餐馆");
                    break;
                }
                
                System.out.println("   [" + visitor.getName() + "] 选择了 " + restaurant.getRestaurantName());
                
                // 尝试取餐
                try {
                    Restaurant.Meal meal = restaurant.consumeMeal(visitor);
                    if (meal != null) {
                        mealsObtained++;
                        System.out.println("   😋 [" + visitor.getName() + "] 在 " + 
                                           restaurant.getRestaurantName() + " 享用 " + 
                                           meal.getMealName() + " (¥" + meal.getPrice() + ") " +
                                           "[" + mealsObtained + "/" + mealCount + "]");
                        
                        // 模拟用餐时间
                        Thread.sleep(random.nextInt(500) + 300);
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
                
                // 如果还需要更多餐品，短暂休息后继续
                if (mealsObtained < mealCount) {
                    Thread.sleep(random.nextInt(200) + 100);
                }
            }
            
            System.out.println("✅ 游客 " + visitor.getName() + " 在美食街用餐完毕\n");
            
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 游客离开美食街
            foodStreet.visitorLeave(visitor);
        }
    }
    
    /**
     * 游客随机进入美食街就餐（默认吃1-3份餐）
     * 
     * @param visitor 要就餐的游客
     */
    public void visitorGoToFoodStreet(BaseVisitor visitor) {
        int mealCount = random.nextInt(3) + 1; // 1-3份餐
        visitorGoToFoodStreet(visitor, mealCount);
    }
    
    /**
     * 随机选择一个餐馆
     * 使用美食街的推荐算法或随机选择
     * 
     * @return 选中的餐馆，如果没有可用餐馆则返回null
     */
    private Restaurant selectRandomRestaurant() {
        FoodStreet foodStreet = getFoodStreet();
        
        if (foodStreet == null) {
            return null;
        }
        
        // 70%概率使用推荐系统（选择排队最少的），30%概率随机选择
        if (random.nextDouble() < 0.7) {
            return foodStreet.recommendRestaurant();
        } else {
            return foodStreet.getRandomRestaurant();
        }
    }
    
    // ==================== 状态查询方法 ====================
    
    /**
     * 获取游乐园状态信息
     * 
     * @return 状态信息字符串
     */
    public String getParkStatus() {
        FoodStreet foodStreet = getFoodStreet();
        
        StringBuilder sb = new StringBuilder();
        sb.append("\n╔════════════════════════════════════════════════╗\n");
        sb.append(String.format("║  %s 状态信息\n", parkName));
        sb.append("╠════════════════════════════════════════════════╣\n");
        sb.append(String.format("║  当前游客数: %d 人\n", peopleNum));
        sb.append(String.format("║  游乐项目数: %d 个\n", projects.size()));
        sb.append(String.format("║  美食街状态: %s\n", 
                  foodStreet != null ? (foodStreet.isOpen() ? "✅ 营业中" : "🔒 已打烊") : "❌ 未开放"));
        if (foodStreet != null) {
            sb.append(String.format("║  美食街餐馆数: %d 家\n", foodStreet.getRestaurantCount()));
        }
        sb.append("╚════════════════════════════════════════════════╝\n");
        
        return sb.toString();
    }
    
    /**
     * 获取美食街统计信息
     * 
     * @return 统计信息字符串
     */
    public String getFoodStreetStatistics() {
        FoodStreet foodStreet = getFoodStreet();
        
        if (foodStreet == null) {
            return "美食街尚未开放";
        }
        return foodStreet.getStatistics();
    }
    
    // ==================== Getter和Setter方法 ====================
    
    public String getParkName() {
        return parkName;
    }
    
    public void setParkName(String parkName) {
        this.parkName = parkName;
    }
    
    public int getPeopleNum() {
        return peopleNum;
    }
    
    public void setPeopleNum(int peopleNum) {
        this.peopleNum = peopleNum;
    }
    
    public BaseVisitor[] getVisitors() {
        return visitors.toArray(new BaseVisitor[0]);
    }
    
    public void setVisitors(BaseVisitor[] visitors) {
        this.visitors = new ArrayList<>();
        if (visitors != null) {
            for (BaseVisitor visitor : visitors) {
                this.visitors.add(visitor);
            }
        }
        this.peopleNum = this.visitors.size();
    }
    
    @Override
    public String toString() {
        return String.format("Park{name='%s', visitors=%d, projects=%d, hasFoodStreet=%s}", 
                             parkName, peopleNum, projects.size(), getFoodStreet() != null);
    }
}
